package org.aj.web.exception.error;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aj.base.web.response.ResponseResult;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

/**
 *
 *
 * @description: 修改自定义返回提示
 * @author: jcj
 * @date: 2021/1/13 14:40
 **/
@Order(Ordered.HIGHEST_PRECEDENCE+1)
public class CustomErrorAttributes extends DefaultErrorAttributes {

    //由调用者来决定使用哪个日志框架
    private static final Log log = LogFactory.getLog(CustomErrorAttributes.class);

    @Value("${custom.tips.not-found:Not Found}")
    private String notFoundTip;


    /**
     * description  {
     *     "timestamp": "2023-03-12 21:49:35",
     *     "status": 405,
     *     "error": "Method Not Allowed",
     *     "path": "/cmnSysDictionaries/secondaryList"
     * }
     * @author aj
     * date 2023/3/12 21:54
     * @param webRequest
     * @param options
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {

        if(!options.isIncluded(ErrorAttributeOptions.Include.MESSAGE)){
            //方便拿到更详细的错误信息
           options = options.including(ErrorAttributeOptions.Include.MESSAGE);
        }

        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
        //得到状态码
        Object status = errorAttributes.get("status");
        //得到提示语
        Object error = errorAttributes.get("error");

        Object detailMsg = errorAttributes.get("message");

        if(ObjectUtils.isNotEmpty(detailMsg)){
            error = detailMsg;
        }

        //移除掉不符合现有返回结构体的键值
        //errorAttributes.remove("exception");

        // errorAttributes.remove("timestamp");

        errorAttributes.remove("error");
        errorAttributes.remove("message");
        //处理404状态码下的返回结构体
        int statusCode = (int) status;
        if(HttpStatus.NOT_FOUND.value() == statusCode){

            error = notFoundTip;
        }

        try {
            ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
            //转成json 字符串
            String jsonStr = objectMapper.writeValueAsString(ResponseResult.error(error.toString(), statusCode));

            //json转成map
            Map<String, Object> map = objectMapper.readValue(jsonStr, Map.class);

            //由于在返回的时候会从此map里面key 为status 获取状态码故不能移除
            map.put("status",statusCode);

            //放入之前的map
            errorAttributes.putAll(map);

            return errorAttributes;
        } catch (JsonProcessingException e) {
            log.error("自定义错误提示语失败，处理失败:",e);
        }

        return errorAttributes;
    }



}
